home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / TransSkel Pascal 2.5 / TransSkel / MultiSkel ƒ / MSkelZoom.p < prev    next >
Encoding:
Text File  |  1994-12-12  |  5.0 KB  |  212 lines  |  [TEXT/PJMM]

  1. {    TransSkel multiple-window demonstration: ZoomRect module}
  2.  
  3. {    This module handles a window in which successive randomly generated}
  4. {    rectangles are smoothly interpolated into one another.  The display}
  5. {    is white on black, which results in some interesting problems (see}
  6. {    ZDrawGrowBox, for instance).  The display adjusts itself to the size}
  7. {    of the window, so that the zoom series always lie entirely within}
  8. {    the window.  Clicking the mouse in the window pauses the display until}
  9. {    the button is released.}
  10.  
  11. {    14 June 1986        Paul DuBois}
  12. {    7 January 1987    ported to LightSpeed Pascal by Owen Hartnett            }
  13. {    Ωhm Software Company.                                                    }
  14.  
  15.  
  16. unit MSkelZoom;
  17.  
  18. interface
  19.  
  20.     uses
  21. {$IFC UNDEFINED THINK_PASCAL}
  22.         Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, 
  23. {$ENDC}
  24.         MultiSkelGlobals, common, TransSkel;
  25.  
  26.     procedure ZoomWindInit;
  27.  
  28. implementation
  29.  
  30.  
  31.     const
  32.         zoomSteps = 15;        { # rects in interpolative series }
  33.  
  34.     var
  35.         zRect: array[0..zoomSteps] of Rect;        { set of interpolated rectangles }
  36.         zSrcRect: Rect;
  37.         sizeX, sizeY: integer;                { size of window in pixels }
  38.  
  39.     procedure SetZoomSize;
  40.  
  41.         var
  42.             r: Rect;
  43.  
  44.     begin
  45.         r := zoomWind^.portRect;
  46.         r.right := r.right - 15;                { don't use right edge }
  47.         sizeX := r.right;
  48.         sizeY := r.bottom;
  49.     end;
  50.  
  51. {    return integer between zero and max (inclusive).  assumes max is}
  52. {    non-negative.}
  53.  
  54.     function Rand (max: integer): integer;
  55.  
  56.         var
  57.             t: integer;
  58.  
  59.     begin
  60.         t := Random;
  61.         if (t < 0) then
  62.             t := -t;
  63.         Rand := t mod (max + 1);
  64.     end;
  65.  
  66. {    Interpolate one rectangle smoothly into another.  Erase the previous}
  67. {    series as the new one is drawn.}
  68.  
  69.     procedure zoomRect (r1, r2: Rect);
  70.  
  71.         var
  72.             r1left, r1top: integer;
  73.             l, t: integer;
  74.             j: integer;
  75.             hDiff, vDiff, widDiff, htDiff: integer;
  76.             r, b: integer;
  77.             rWid, rHt: integer;
  78.  
  79.     begin
  80.         r1left := r1.left;
  81.         r1top := r1.top;
  82.         hDiff := r2.left - r1left;        {positive if moving to right }
  83.         vDiff := r2.top - r1top;        {positive if moving down        }
  84.  
  85.         rWid := r1.right - r1left;
  86.         rHt := r1.bottom - r1top;
  87.         widDiff := (r2.right - r2.left) - rWid;
  88.         htDiff := (r2.bottom - r2.top) - rHt;
  89.  
  90. {    order of evaluation is important in the rect coordinate calculations.}
  91. {    since all arithmetic is integer, you can't save time by calculating}
  92. {    j/zoomSteps and using that - it'll usually be zero.}
  93.  
  94.         for j := 1 to zoomSteps do
  95.             begin
  96.                 FrameRect(zRect[j - 1]);                { erase a rectangle }
  97.                 l := r1left + (hDiff * j) div zoomSteps;
  98.                 t := r1top + (vDiff * j) div zoomSteps;
  99.                 r := l + rWid + (widDiff * j) div zoomSteps;
  100.                 b := t + rHt + (htDiff * j) div zoomSteps;
  101.                 SetRect(zRect[j - 1], l, t, r, b);
  102.                 FrameRect(zRect[j - 1]);
  103.             end;
  104.     end;
  105.  
  106.     procedure Idle;
  107.  
  108.         var
  109.             i: integer;
  110.             pt1, pt2: Point;
  111.             dstRect: Rect;
  112.  
  113.     begin
  114.         SetPt(pt1, Rand(sizeX), Rand(sizeY));    { generate new rect }
  115.         SetPt(pt2, Rand(sizeX), Rand(sizeY));    { and zoom to it        }
  116.         Pt2Rect(pt1, pt2, dstRect);
  117.         SetWindClip(zoomWind);            { don't draw in right edge }
  118.         ZoomRect(zSrcRect, dstRect);
  119.         ResetWindClip;
  120.         zSrcRect := dstRect;
  121.     end;
  122.  
  123. {    just pause zoom display while mouse down}
  124.  
  125.     procedure Mouse (thePt: point; t: longint; mods: integer);
  126.     begin
  127.         while (StillDown) do
  128.             ;  { wait until mouse button released }
  129.     end;
  130.  
  131. {    Draw the grow box in white on black.  This is tricky:  if the window}
  132. {    is inactive, the grow box will be drawn black, as it should be.  But}
  133. {    if the window is active, the box will STILL be drawn black on white!}
  134. {    So have to check whether the window is active or not.  The test for}
  135. {    active has to be done carefully:  the window manager stores 255 and 0}
  136. {    for true and false, not real boolean values.}
  137.  
  138.     procedure ZDrawGrowBox;
  139.         var
  140.             r: Rect;
  141.             zoomPeek: WindowPeek;
  142.  
  143.     begin
  144.         PenMode(notPatCopy);
  145.         DrawGrowBox(zoomWind);
  146.         PenMode(patXor);
  147.         zoomPeek := WindowPeek(zoomWind);
  148.         if (zoomPeek^.hilited) then    { grow box draw in white }
  149.             begin                        { no matter what if active }
  150.                 r := zoomWind^.portRect;                { - invert to fix }
  151.                 r.left := r.right - 14;
  152.                 r.top := r.bottom - 14;
  153.                 InvertRect(r);
  154.             end;
  155.     end;
  156.  
  157.     procedure Update (resized: Boolean);
  158.  
  159.         var
  160.             i: integer;
  161.     begin
  162.         EraseRect(zoomWind^.portRect);
  163.         ZDrawGrowBox;
  164.         SetWindClip(zoomWind);
  165.         for i := 0 to zoomSteps - 1 do
  166.             FrameRect(zRect[i]);
  167.         ResetWindClip;
  168.         if resized then
  169.             SetZoomSize;    { adjust to new window size }
  170.     end;
  171.  
  172.     procedure Activate (active: Boolean);
  173.  
  174.     begin
  175.         ZDrawGrowBox;
  176.         if active then
  177.             DisableItem(editMenu, 0)
  178.         else
  179.             EnableItem(editMenu, 0);
  180.         DrawMenuBar;
  181.     end;
  182.  
  183.     procedure Halt;
  184.     begin
  185.         CloseWindow(zoomWind);
  186.     end;
  187.  
  188.     procedure ZoomWindInit;
  189.  
  190.         var
  191.             i: integer;
  192.     begin
  193.         zoomWind := GetNewWindow(zoomWindRes, nil, WindowPtr(-1));
  194.         dummy := SkelWindow(zoomWind, @Mouse, nil, @Update, @Activate, nil, @Halt, @Idle, true);
  195.             { ignore key clicks }
  196.             { no close proc }
  197.         { when done with window }
  198.         { draw a new series }
  199.             { run only when frontmost }
  200.  
  201.         SetZoomSize;
  202. {$IFC UNDEFINED THINK_PASCAL}
  203.         BackPat(qd.black);
  204. {$ELSEC}
  205.         BackPat(black);
  206. {$ENDC}
  207.         PenMode(patXor);
  208.         SetRect(zSrcRect, 0, 0, 0, 0);
  209.         for i := 0 to zoomSteps - 1 do        { initialize rect array }
  210.             zRect[i] := zSrcRect;
  211.     end;
  212. end.